#ifndef CARD_H
#define CARD_H

#include <QSet>
#include <QVector>
#include <QWidget>
#include <QThread>

#include "player.h"

class Card {
public:
    enum CardColor {
        Diamond,
        Club,
        Heart,
        Spade
    };
    enum CardPoint {
        Point_3,
        Point_4,
        Point_5,
        Point_6,
        Point_7,
        Point_8,
        Point_9,
        Point_10,
        Point_11,  //J
        Point_12,  //Q
        Point_13,  //K
        Point_14,  //A
        Point_15,  //2
    };
    Card();
    Card(CardPoint point, CardColor color);
    void setPoint(CardPoint point);
    void setColor(CardColor color);
    CardPoint point() const;
    CardColor color() const;

private:
    CardPoint mypoint;
    CardColor mycolor;
};

// 对象比较
bool smallPoint(const Card& c1, const Card& c2);
bool bigPoint(const Card& c1, const Card& c2);
bool operator<(const Card& c1, const Card& c2);
bool operator>(const Card& c1, const Card& c2);

// 操作符重载 (==) 用于Qset存储
bool operator==(const Card& left, const Card& right);

// 重写全局函数 qHash 用于Qset 存储
uint qHash(const Card& card);

// 定义类型的别名
using CardList = QVector<Card>;

class Cards {
public:
    enum SetOrder { Asc, Desc, NoSort };  //枚举 排序方式
    Cards();
    Cards(const Card& card);

    // 添加扑克牌，发牌
    void add(const Card& card);             //添加一张
    void add(const Cards& cards);           //添加多张
    void add(const QVector<Cards>& cards);  //添加

    // 一次性插入多个数据 (操作符重载 << )，单纯重载操作符，返回引用，可链式操作
    Cards& operator<<(const Card& card);
    Cards& operator<<(const Cards& cards);

    // 删除扑克牌，出牌
    void remove(const Card& card);    //删除一张
    void remove(const Cards& cards);  //删除多张
    void remove(const QVector<Cards>& cards);

    // 扑克牌的数量
    int cardCount();
    // 是否为空
    bool isEmpty();
    void clear();

    // 最大点数
    Card::CardPoint maxPoint();
    // 最小点数
    Card::CardPoint minPoint();
    // 指定点数的牌的数量
    int pointCount(Card::CardPoint point);
    // 某张牌是否在集合中
    bool contains(const Card& card);
    bool contains(const Cards& cards);

    // 随机取出一张扑克牌
    Card takeRandomCard();

    CardList toCardList(SetOrder type = Desc);

    // 测试函数, 打印所有的卡牌信息
    void printCardDebug();

private:
    QSet<Card> mycardset;  // Qset不能自动排序，需要自己实现；STL 中的 set 可以自动排序
};
#endif  // CARD_H
